package cn.jinjimi.app.poster.presenter;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;

import cn.jinjimi.base.preference.PreferenceManager;
import cn.jinjimi.base.util.ImageUtils;
import cn.jinjimi.base.util.MD5Utils;
import cn.jinjimi.base.util.SharePlatForm;
import cn.jinjimi.base.util.StringUtils;
import cn.jinjimi.framework.helper.annotation.EventTrace;
import cn.jinjimi.framework.helper.annotation.EventTraceParam;
import cn.jinjimi.app.AccountManager;
import cn.jinjimi.app.ShareProxy;
import cn.jinjimi.app.bean.EventDataField;
import cn.jinjimi.app.bean.EventID;
import cn.jinjimi.app.bean.BundleKey;
import cn.jinjimi.domain.ServiceManager;
import cn.jinjimi.domain.store.PosterStore;
import cn.jinjimi.app.poster.bean.ContinueMarkData;
import cn.jinjimi.app.poster.bean.PosterDetailInfo;
import cn.jinjimi.app.poster.bean.PosterInfo;
import cn.jinjimi.app.poster.bean.PosterMarkDto;
import cn.jinjimi.app.poster.cache.CacheBitmapController;
import cn.jinjimi.app.poster.fragment.PosterContainerFragment;
import cn.jinjimi.app.poster.interfaces.PosterFragmentPopupView;
import cn.jinjimi.app.presenter.IXrkPresenter;
import cn.jinjimi.app.main.dialog.ShareDialog;
import cn.jinjimi.app.bean.SharePrefKeys;

import java.lang.ref.WeakReference;
import java.util.concurrent.Callable;

import bolts.Continuation;
import bolts.Task;

/**
 * Created by lforxeverc on 16/9/22.
 */

public class SharePosterPresenter implements IXrkPresenter {
    private PosterFragmentPopupView mView;
    private Activity mContext;
    private CacheBitmapController mCacheBitmapController;
    private int mCurrentPosition;
    private MyHandler mHandler;
    private static final int LOAD_POSTER = 1;
    private long lastLoadTs;

    PosterInfo posterInfo;
    int position;
    boolean forceRefresh;
    private int categoryCode;
    private final String DISPLAY_MARK_KEY_JINJU = "display_mark_key_jinju";
    private final String DISPLAY_MARK_KEY_POSTER = "display_mark_key_poster";

    @Override
    public void onCreate() {

    }

    @Override
    public void onDestroy() {
        if (mCacheBitmapController != null) {
            mCacheBitmapController.onDestroy();
            mCacheBitmapController = null;
        }
        mContext = null;
    }

    private static class MyHandler extends Handler {
        final WeakReference<SharePosterPresenter> mPresent;

        public MyHandler(SharePosterPresenter mPresent) {
            super();
            this.mPresent = new WeakReference<>(mPresent);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mPresent != null && mPresent.get() != null) {
                SharePosterPresenter pre = mPresent.get();
                if (msg.what == LOAD_POSTER) {
                    mPresent.get().startLoadPosterInternal(pre.posterInfo, pre.position, pre.forceRefresh);
                }
            }
        }
    }

    public SharePosterPresenter(Activity ctx, PosterFragmentPopupView view) {
        mView = view;
        mContext = ctx;
        mCacheBitmapController = new CacheBitmapController();
        mHandler = new MyHandler(this);
    }

    public void startLoadPoster(final PosterInfo posterInfo, final int position, final boolean forceRefresh) {
        mCurrentPosition = position;
        this.posterInfo = posterInfo;
        this.position = position;
        this.forceRefresh = forceRefresh;
        mHandler.removeMessages(LOAD_POSTER);
        long currentTs = System.currentTimeMillis();
        mHandler.sendEmptyMessageDelayed(LOAD_POSTER, lastLoadTs == 0 || currentTs - lastLoadTs >= 300 ? 0 : 300);
        lastLoadTs = currentTs;

    }

    public void startLoadPosterInternal(final PosterInfo posterInfo, final int position, final boolean forceRefresh) {
        mCurrentPosition = position;
        //不是强制刷新且有水印信息时直接判断是否有缓存
        if (!forceRefresh && posterInfo.posterDetailInfo != null) {
            String markUrl = null;
            final String backUrl = posterInfo.posterDetailInfo.getBackgroundUrl();

            PosterDetailInfo.WaterMark mark = posterInfo.posterDetailInfo.getWaterMark();
            if (mark != null)
                markUrl = mark.getWaterMarkUrl();
            //空水印模版海报
            final boolean onlyBackUrl = (mark == null || StringUtils.isEmpty(markUrl)) || !isDisplayMark();
            //缓存的大图和水印url都不为空时查询是否存在缓存图片数据
            if (!StringUtils.isEmpty(backUrl)) {

                final String cacheKey = onlyBackUrl ? backUrl : getCacheKey(backUrl, markUrl);
                Task.callInBackground(new Callable<Bitmap>() {
                    @Override
                    public Bitmap call() throws Exception {
                        //子线程获取缓存数据
                        return mCacheBitmapController.getCacheData(cacheKey);
                    }
                }).continueWith(new Continuation<Bitmap, Object>() {
                    @Override
                    public Object then(Task<Bitmap> task) throws Exception {
                        Bitmap cacheBm = task.getResult();
                        //缓存可用时直接返回缓存
                        if (cacheBm != null && !cacheBm.isRecycled()) {
                            mView.loadSuccess(position, cacheBm);
                        } else {
                            //直接获取两个图片信息并合成
                            loadImages(posterInfo, posterInfo.posterDetailInfo, position, onlyBackUrl);
                        }
                        return null;
                    }
                }, Task.UI_THREAD_EXECUTOR);

            } else {
                fetchMarkInfo(posterInfo, position, forceRefresh);
            }

        } else {
            fetchMarkInfo(posterInfo, position, forceRefresh);
        }

    }

    //从网络获取大图和水印信息
    private void fetchMarkInfo(final PosterInfo posterInfo, final int position, final boolean forceRefresh) {
        if (mCurrentPosition != position)
            return;
        mView.showThumbnailUrl(posterInfo, position);
        mView.showLoading();
        try {
            Task.callInBackground(new Callable<PosterMarkDto>() {
                @Override
                public PosterMarkDto call() throws Exception {
                    return ServiceManager.getService(PosterStore.class).fetchPosterMarkInfo(posterInfo.templateId, forceRefresh);
                }
            }).continueWith(new Continuation<PosterMarkDto, ContinueMarkData>() {
                @Override
                public ContinueMarkData then(Task<PosterMarkDto> task) throws Exception {
                    if (mCurrentPosition != position)
                        return null;
                    //解析海报和水印信息
                    PosterMarkDto data = task.getResult();
                    if (data != null && data.isOk) {
                        PosterDetailInfo info = data.getData();
                        if (info != null) {
                            String backUrl, markUrl = null;
                            backUrl = info.getBackgroundUrl();
                            PosterDetailInfo.WaterMark mark = info.getWaterMark();
                            if (mark != null) {
                                markUrl = mark.getWaterMarkUrl();
                            }
                            return new ContinueMarkData(backUrl, markUrl, info);
                        }
                    }
                    return null;
                }
            }).continueWith(new Continuation<ContinueMarkData, Object>() {
                @Override
                public Object then(Task<ContinueMarkData> task) throws Exception {
                    final ContinueMarkData data = task.getResult();
                    //海报url和水印url都不为空直接去检查缓存
                    if (data != null) {
                        boolean isBackUrlEmpty = StringUtils.isEmpty(data.getBackgroundUrl());
                        boolean isMarkEmpty = StringUtils.isEmpty(data.getMarkUrl()) || !isDisplayMark();
                        if (!isBackUrlEmpty) {
                            loadImages(posterInfo, data.getMaskInfo(), position, isMarkEmpty);
                            return null;
                        }
                    }
                    Task.call(new Callable<Object>() {
                        @Override
                        public Object call() throws Exception {
                            mView.loadFail(position);
                            return null;
                        }
                    }, Task.UI_THREAD_EXECUTOR);
                    return null;
                }
            });
        } catch (Exception e) {
        }
    }

    /**
     *  是否显示个人信息
     * @return
     */
    public boolean isDisplayMark() {
        if (categoryCode == PosterContainerFragment.DataType.JINJU_POSTER) {
            return PreferenceManager.getBooleanData(DISPLAY_MARK_KEY_JINJU + AccountManager.getInstance().getAccount().ssoid, true);
        } else {
            return PreferenceManager.getBooleanData(DISPLAY_MARK_KEY_POSTER + AccountManager.getInstance().getAccount().ssoid, true);
        }
    }

    /**
     * 设置是否显示个人信息
     * @param display
     */
    public void setDisplayMark(boolean display) {
        if (categoryCode == PosterContainerFragment.DataType.JINJU_POSTER) {
            PreferenceManager.setData(DISPLAY_MARK_KEY_JINJU + AccountManager.getInstance().getAccount().ssoid, display);
        } else {
            PreferenceManager.setData(DISPLAY_MARK_KEY_POSTER + AccountManager.getInstance().getAccount().ssoid, display);
        }
    }

    private void loadImages(final PosterInfo posterInfo, final PosterDetailInfo detailInfo, final int position, final boolean onlyback) {
        if (mCurrentPosition != position)
            return;
        final String backgroundUrl = detailInfo.getBackgroundUrl();
        final String markUrl = onlyback ? null : detailInfo.getWaterMark().getWaterMarkUrl();
        final Boolean[] urlSuccess = new Boolean[2];
        final Bitmap[] bitmaps = new Bitmap[2];
        Task.callInBackground(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                ImageUtils.ILoadImageListener listener = new ImageUtils.ILoadImageListener() {
                    @Override
                    public void onResult(int code, String url, final Bitmap bitmap) {
                        if (mCurrentPosition != position)
                            return;
                        if (url.equals(backgroundUrl)) {
                            boolean isSuccess = code == ImageUtils.ILoadImageListener.CODE_SUCCESS;
                            urlSuccess[0] = isSuccess;
                            bitmaps[0] = bitmap;
                            if (isSuccess)
                                mCacheBitmapController.saveCacheData(url, bitmap);
                        }
                        if (url.equals(markUrl)) {
                            boolean isSuccess = code == ImageUtils.ILoadImageListener.CODE_SUCCESS;
                            urlSuccess[1] = isSuccess;
                            bitmaps[1] = bitmap;
                            if (isSuccess)
                                mCacheBitmapController.saveCacheData(url, bitmap);
                        }
                        final Boolean backSuccess = urlSuccess[0];
                        final Boolean markSuccess = urlSuccess[1];
                        //两个图片的都跑完了下载（成功或失败）
                        if (!onlyback && backSuccess != null && markSuccess != null) {
                            //两张图都成功，合成
                            if (backSuccess && markSuccess) {
                                final Bitmap bm = combineImages(bitmaps[0], bitmaps[1], detailInfo.getWaterMark().getX(), detailInfo.getWaterMark().getY());
                                Task.call(new Callable<Object>() {
                                    @Override
                                    public Object call() throws Exception {
                                        if (bm == null) {
                                            mView.loadFail(position);
                                            return null;
                                        }
                                        synchronized (bm) {
                                            if (bm != null && !bm.isRecycled()) {
                                                posterInfo.posterDetailInfo = detailInfo;
                                                mView.updatePosterInfo(posterInfo, position);
                                                mView.loadSuccess(position, bm);
                                            } else {
                                                mView.loadFail(position);
                                            }
                                            return null;
                                        }
                                    }
                                }, Task.UI_THREAD_EXECUTOR);

                                //缓存起这次的数据
                                if (bm != null && !bm.isRecycled())
                                    mCacheBitmapController.saveCacheData(getCacheKey(backgroundUrl, markUrl), bm);

                            } else {
                                Task.call(new Callable<Object>() {
                                    @Override
                                    public Object call() throws Exception {
                                        mView.loadFail(position);
                                        return null;
                                    }
                                }, Task.UI_THREAD_EXECUTOR);
                            }
                        } else if (backSuccess != null && onlyback) {
                            Task.call(new Callable<Object>() {
                                @Override
                                public Object call() throws Exception {
                                    if (backSuccess) {
                                        posterInfo.posterDetailInfo = detailInfo;
                                        mView.updatePosterInfo(posterInfo, position);
                                        mView.loadSuccess(position, bitmaps[0]);
                                    } else {
                                        mView.loadFail(position);
                                    }
                                    return null;
                                }
                            }, Task.UI_THREAD_EXECUTOR);
                        }
                    }
                };

                Bitmap backBm = mCacheBitmapController.getCacheData(backgroundUrl);
                if (backBm == null || backBm.isRecycled()) {
                    if (!StringUtils.isEmpty(backgroundUrl))
                        ImageUtils.downloadImage(null, backgroundUrl, listener, false);
                    else
                        listener.onResult(ImageUtils.ILoadImageListener.CODE_FAIL, backgroundUrl, backBm);

                } else {
                    listener.onResult(ImageUtils.ILoadImageListener.CODE_SUCCESS, backgroundUrl, backBm);
                }
                Bitmap markBm = mCacheBitmapController.getCacheData(markUrl);
                if (markBm == null || markBm.isRecycled()) {
                    if (!StringUtils.isEmpty(markUrl))
                        ImageUtils.downloadImage(null, markUrl, listener, false);
                    else
                        listener.onResult(ImageUtils.ILoadImageListener.CODE_FAIL, markUrl, markBm);
                } else {
                    listener.onResult(ImageUtils.ILoadImageListener.CODE_SUCCESS, markUrl, markBm);
                }

                return null;
            }
        });
    }

    public void startSharePoster(final Bitmap bitmap, final PosterInfo posterInfo, final int categoryCode, final String source) {
        ShareDialog.Builder builder = new ShareDialog.Builder();
        builder.Bitmap(bitmap).ShareType(ShareProxy.ShareType.IMAGE).SharePlatForm(SharePlatForm.getShareMultiPlatforms());
        ShareDialog shareDialog = builder.build(mContext);
        shareDialog.setOnSharedListener(new ShareDialog.SharedListener() {
            @Override
            public void onSuccess() {
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onFail() {

            }

            @Override
            public void onStart() {

                String fromAndType = categoryCode == PosterContainerFragment.DataType.PRODUCT_POSTER ? EventID.FROM_POSTER_PRODUCT :
                        (categoryCode == PosterContainerFragment.DataType.INFORMATION_POSTER ? EventID.FROM_POSTER_INFORMATION : EventID.FROM_POSTER_QUOTES);
                String sourceTemp = (categoryCode == PosterContainerFragment.DataType.JINJU_POSTER && !StringUtils.isEmpty(source)) ? source : mContext.getIntent().getStringExtra(BundleKey.PARAM_POSTER_SOURCE);

                analyse(PreferenceManager.getStringData(SharePrefKeys.PREF_SHARE_ID), String.valueOf(posterInfo.templateId), fromAndType, fromAndType, sourceTemp);
                try {
                    Task.callInBackground(new Callable<Void>() {
                        @Override
                        public Void call() throws Exception {
                            ServiceManager.getService(PosterStore.class).sendShareTemplate(posterInfo.templateId);
                            return null;
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }

                mView.dismissSelf();
            }
        });
        shareDialog.show();

    }

    @EventTrace(EventID.APP_SHARE_TYPE_ID)
    private void analyse(@EventTraceParam(EventDataField.ParamPostion) String position, @EventTraceParam(EventDataField.ParamId) String id,
                         @EventTraceParam(EventDataField.ParamFrom) String from, @EventTraceParam(EventDataField.ParamType) String type,
                         @EventTraceParam(EventDataField.ParamSource) String source) {
    }

    private String getCacheKey(String backgroundUrl, String markUrl) {
        return MD5Utils.MD5(backgroundUrl + markUrl);

    }

    private synchronized Bitmap combineImages(Bitmap source, Bitmap logo, int x, int y) {
        if (source != null && !source.isRecycled() && logo != null && !logo.isRecycled()) {
            Bitmap bm = Bitmap.createBitmap(source.copy(Bitmap.Config.ARGB_8888, true), 0, 0, source.getWidth(), source.getHeight());
            Canvas canvas = new Canvas(bm);
            canvas.drawBitmap(logo.copy(Bitmap.Config.ARGB_8888, true), x, y, new Paint(Paint.ANTI_ALIAS_FLAG));
            return bm;
        }
        return null;
    }

    public void setCategoryCode(int categoryCode) {
        this.categoryCode = categoryCode;
    }
}